-
Notifications
You must be signed in to change notification settings - Fork 191
feat: Implement email OTP authentication #2414
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
ConsoleProject ID: Sites (2)
Note Appwrite has a Discord community with over 16 000 members. |
WalkthroughAdds a passwordless email OTP sign-in flow and a resend cooldown component. The login page now toggles between password login and sending an email sign-in code; password input is not required and email autofocus removed. A new email-otp page verifies 6-digit codes, creates console sessions, supports resending tokens, tracks analytics, shows notifications, and redirects based on coupon, campaign, or explicit redirect. A load function fetches coupon/campaign data from URL params. The send-verification modal was refactored to use a new ResendCooldown component with localStorage persistence. Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/routes/(public)/(guest)/login/+page.svelte
(2 hunks)src/routes/(public)/(guest)/login/email-otp/+page.svelte
(1 hunks)src/routes/(public)/(guest)/login/email-otp/+page.ts
(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/routes/(public)/(guest)/login/email-otp/+page.ts (1)
src/lib/stores/sdk.ts (1)
sdk
(147-170)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: e2e
- GitHub Check: build
`${base}/login/email-otp?email=${encodeURIComponent(mail)}&userId=${sessionToken.userId}` | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Preserve existing query params when switching to the OTP flow
Right now we build the OTP URL with only email
and userId
, which strips any pre-existing query params (code
, campaign
, redirect
, etc.). The new loader in email-otp/+page.ts
expects those params to rehydrate data
, so dropping them prevents us from ever hitting the coupon/campaign apply-credit paths and also loses any redirect target after a successful OTP login. Please carry forward the current search params before adding email
/userId
.
- await goto(
- `${base}/login/email-otp?email=${encodeURIComponent(mail)}&userId=${sessionToken.userId}`
- );
+ const params = new URLSearchParams(window.location.search);
+ params.set('email', mail);
+ params.set('userId', sessionToken.userId);
+
+ await goto(`${base}/login/email-otp?${params.toString()}`);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
`${base}/login/email-otp?email=${encodeURIComponent(mail)}&userId=${sessionToken.userId}` | |
); | |
const params = new URLSearchParams(window.location.search); | |
params.set('email', mail); | |
params.set('userId', sessionToken.userId); | |
await goto(`${base}/login/email-otp?${params.toString()}`); |
🤖 Prompt for AI Agents
In src/routes/(public)/(guest)/login/+page.svelte around lines 34 to 35, the OTP
redirect builds a URL with only email and userId which drops any existing query
params (code, campaign, redirect, etc.); update the URL construction to preserve
current search params by copying the existing location.search (or current
URLSearchParams) into a new URLSearchParams instance, set/overwrite the email
and userId keys, and then append that full query string to
`${base}/login/email-otp` so all original params are carried forward along with
email and userId.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/lib/components/account/sendVerificationEmailModal.svelte (1)
12-57
: Drop the no-oponDestroy
.We still import
onDestroy
but only call an empty handler, so both lines can go. Keeps the component leaner.-import { onDestroy } from 'svelte'; ... -onDestroy(() => {});
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/lib/components/account/sendVerificationEmailModal.svelte
(3 hunks)src/lib/components/resendCooldown.svelte
(1 hunks)src/routes/(public)/(guest)/login/email-otp/+page.svelte
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build
- GitHub Check: e2e
localStorage.removeItem(EMAIL_SENT_KEY); | ||
} | ||
}); | ||
onDestroy(() => {}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
empty?
import { Link } from '@appwrite.io/pink-svelte'; | ||
let { | ||
storageKey = 'resend_cooldown_default', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets not have a default, always mark as required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
svelte5 runes.
try { | ||
disabled = true; | ||
const sessionToken = await sdk.forConsole.account.createEmailToken({ | ||
userId: 'unique', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use ID.unique()
What does this PR do?
Add email OTP as primary login method with separate verification page,
proper Appwrite SDK integration, and dynamic UI switching.
Test Plan
Related PRs and Issues
(If this PR is related to any other PR or resolves any issue or related to any issue link all related PR and issues here.)
Have you read the Contributing Guidelines on issues?
yes
Summary by CodeRabbit
New Features
UX Changes
Reliability